////////////////////////////////////////////////////////////////////////////////
//
//	Original file Name: InputManager.java
//	Originating Author: JWhitefield
//	
//	Description: Manages the input from the controllers 
//
////////////////////////////////////////////////////////////////////////////////

package com.jjw.game.input;

import java.util.ArrayList;
import java.util.List;

import net.java.games.input.Controller;
import net.java.games.input.Controller.Type;
import net.java.games.input.ControllerEnvironment;

import com.jjw.game.ITickable;

public class InputManager implements ITickable{

	//--------------------------------------------------------------------------
	//
	//Properties
	//
	//--------------------------------------------------------------------------
	
	//----------------------------------
	// Public
	//----------------------------------
		
	//----------------------------------
	//  Getters / Setters
	//----------------------------------
	
	//----------------------------------
	// Private
	//----------------------------------
	
	/**
	 * Private instance of this input manager for a singleton 
	 */
	private static InputManager instance = null;
	
	/**
	 * The controller environment which we will use 
	 */
	private ControllerEnvironment controllerEnvironment;
	
	/**
	 * List of all the input devices found in the application 
	 */
	private List<InputDevice> inputDevices = new ArrayList<InputDevice>();
	
	/**
	 * All controllers input device group 
	 */
	private InputDeviceGroup allControllersInputDeviceGroup;
		
	//--------------------------------------------------------------------------
	//
	//  Methods
	//
	//--------------------------------------------------------------------------
	
	//----------------------------------
	// Public
	//----------------------------------
	
	public InputManager() {
		
		//Create the new input devices list 
		this.inputDevices = new ArrayList<InputDevice>();		
		
		//Get the controller environment 
		controllerEnvironment = ControllerEnvironment.getDefaultEnvironment();
		
		//Find all the controllers, when we start the class
		this.findControllers();
	}
	
	/**
	 * Gets an instance of the input manager 
	 */
	public static InputManager getInstance(){
		
		//If one hasn't been created then create an instance of it 
		if( instance == null )
			instance = new InputManager();
		
		//Return the instance
		return instance;
	}

	@Override
	public void tick() {
		
		//Find the currently attached controllers 
		//this.findControllers();
		
		//Loop through each of the controllers ticking them over 
		for( InputDevice inputDevice: this.inputDevices )
			inputDevice.tick();
	}
	
	/**
	 * Create the all controllers input device group so that all controllers can be used to control one thing
	 * 
	 * @return our all controllers group
	 */
	public InputDeviceGroup getAllControllersInputGroup() {
		
		//Do we already have an all controllers group, if not create one
		if( this.allControllersInputDeviceGroup == null )
		{			
			//Create an all controllers group
			this.allControllersInputDeviceGroup = new InputDeviceGroup();
		}
		
		//Set all the input devices as the list for the group
		this.allControllersInputDeviceGroup.setInputDeviceGroup( this.inputDevices );
		
		//Return our new group
		return this.allControllersInputDeviceGroup;
	}
	
	/**
	 * Get all the controllers
	 */
	public List<InputDevice> getAllControllers() {
				
		//Return the list of input devices
		return this.inputDevices;
	}
	
	//----------------------------------
	// Private
	//----------------------------------
	
	/**
	 * Find the controllers which this application has access to 
	 */
	private void findControllers() {
		
		//Get the list of controllers 
		Controller[] controllers = this.controllerEnvironment.getControllers(); 

		//Input device placeholder
		InputDevice device = null;
		
		//Loop through the controller list
		for( Controller controller : controllers )
		{
			//Check for the keyboard controller
			if( controller.getType() == Type.KEYBOARD )
			{
				//Create a new input device controller
				device = new InputDeviceKeyboard( controller );
					
				//Add the device to the list
				this.inputDevices.add( device );
			}
			//Check for the game pad or stick type
			else if( controller.getType() == Type.GAMEPAD || controller.getType() == Type.STICK)
			{
				//Create a new input device controller
				device = new InputDeviceGamePad( controller );
					
				//Add the device to the list
				this.inputDevices.add( device );
			}
		}
		
	}

	/**
	 * Resets the input button states for all the input devices
	 */
	public void resetInputDevicesButtons() {

		//Loop through each device reseting the input buttons
		for( InputDevice device: this.inputDevices )
			device.resetInputButtons();
		
	}
	
	//----------------------------------
	// Overridden / Implemented
	//----------------------------------
}
